package tlv.socket.call;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import tlv.bean.Attr;
import tlv.bean.TlvHwBean;
import tlv.enums.ErrCode;
import tlv.enums.TlvType;
import tlv.socket.Dgram;
import tlv.tools.TlvSkspruce;

/**
 * 西加云杉700E设备认证
 * @author yet
 *
 */
public class SkspruceChapAuthCall implements Callable<String> {
	private DatagramSocket s;
	private InetAddress hostAddress;
	private byte[] buf = new byte[1000];
	private DatagramPacket dp = new DatagramPacket(buf, buf.length);
	private byte[] bufRe = new byte[1000];
	private DatagramPacket dpRe = new DatagramPacket(bufRe, bufRe.length);
	private int port;
	private String userIp;
	private int serialNo;
	private String username;
	private String password;

	@Override
	public String call() throws Exception {
		String result = "105";
		try {
			s.send(Dgram.toDatagram(ReqChallenge(), hostAddress, port));
			s.receive(dp);
			TlvHwBean b = parse(dp.getData());
			if(b.getErrCode()==0){
				s.send(Dgram.toDatagram(ReqAuth(b.getReqId()), hostAddress, port));
				s.receive(dpRe);
				TlvHwBean bre = parse(dpRe.getData());
				switch (bre.getErrCode()) {
				case 0:
					result = Integer.toString(ErrCode.Success.getErrCode());
					System.out.println(ErrCode.Success.getErrCode());
					break;
				case 1:
					result = Integer.toString(ErrCode.Refused.getErrCode());
					System.out.println(ErrCode.Refused.getErrCode());
					break;
				case 2:
					result = Integer.toString(ErrCode.Already.getErrCode());
					System.out.println(ErrCode.Already.getErrCode());
					break;
				case 3:
					result = Integer.toString(ErrCode.Busy.getErrCode());
					System.out.println(ErrCode.Busy.getErrCode());
					break;
				case 4:
					result = Integer.toString(ErrCode.Fail.getErrCode());
					System.out.println(ErrCode.Fail.getErrCode());
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
		return result;
	}
	
	/**
	 * 生成Challenge的请求
	 * @return
	 */
	public byte[] ReqChallenge() {
		List<Attr> attr = new ArrayList<Attr>();
		Attr a = new Attr(1, username.getBytes());
		Attr b = new Attr(2, password.getBytes());
		attr.add(a);
		attr.add(b);
		return TlvSkspruce.buildSkspruce(TlvType.ReqChallenge,serialNo,0, userIp, attr);
	}
	
	/**
	 * 生成认证请求
	 * @param reqId
	 * @return
	 */
	private byte[] ReqAuth(int reqId){
		List<Attr> attr = new ArrayList<Attr>();
		Attr a = new Attr(1, username.getBytes());
		Attr b = new Attr(2, password.getBytes());
		attr.add(a);
		attr.add(b);
		return TlvSkspruce.buildSkspruce(TlvType.ReqAuth,serialNo, reqId, userIp, attr);
	}
	
	/**
	 * 将byte[]转为TlvHwBean
	 * @param a
	 * @return
	 */
	private TlvHwBean parse(byte[] a){
		return TlvSkspruce.parseHw(a);
	}
	
	/**
	 * @param ip AC的ip地址
	 * @param port AC监听的端口
	 * @param userIp 用户内网ip
	 * @param username 用户名
	 * @param password 密码
	 * @param serialNo
	 */
	public SkspruceChapAuthCall(String ip, int port,String userIp,String username,String password,int serialNo) {
		this.port = port;
		this.userIp = userIp;
		this.serialNo = serialNo;
		this.username = username;
		this.password = password;
		try {
			s = new DatagramSocket();
			hostAddress = InetAddress.getByName(ip);

		} catch (UnknownHostException e) {
			System.err.println("Cannot find host");
			System.exit(1);
		} catch (SocketException e) {
			System.err.println("Can't open socket");
			e.printStackTrace();
			System.exit(1);
		}
		System.out.println("请求开始");
	}
}
